package com.lyz.core.impl;

import org.apache.log4j.Logger;

import com.lyz.config.ConfigFactory;
import com.lyz.config.IConfig;
import com.lyz.file.IFileFetcher;
import com.lyz.file.IFileHandler;
import com.lyz.file.IFileProcess;
import com.lyz.file.IFileQueue;
import com.lyz.file.impl.LogFileFetcher;
import com.lyz.file.impl.LogFileFetcher4FixName;
import com.lyz.file.impl.LogFileHandler;
import com.lyz.file.impl.LogFileProcess;
import com.lyz.file.impl.LogFileQueue;
import com.lyz.monitor.IMonitor;
import com.lyz.monitor.impl.RealTimeMonitor;
import com.lyz.monitor.impl.RealTimeMonitorData;
import com.lyz.remote.IMsgHandler;
import com.lyz.remote.impl.SocketMsgHandler;
import com.lyz.util.PropertiesUtil;
import com.lyz.util.SleepUtil;

public class TransferService extends Thread {
	
	private static final Logger logger = Logger.getLogger(TransferService.class);
	
	private String tag = null;
	
	private IConfig config = null;
	
	private IMonitor monitor = null;
	
	public TransferService(String tag){
		this.tag = tag;
		this.setName(tag);
		config = ConfigFactory.getConfig();
		monitor = RealTimeMonitor.getInstance();
	}
	
	
	public String getTag(){
		
		return tag;
	}

	public void run(){
		if(tag == null || "".equals(tag.trim())){
			return;
		}
				
		Context context = new Context(tag);
		
		logger.info("start "+tag+" service...");
		IFileProcess proc = new LogFileProcess(tag);
		
		logger.info("new file queue...");
		IFileQueue queue = new LogFileQueue();
		
		logger.info("new file fetcher...");
		IFileFetcher fetcher = FactoryService.getFileFetcher(config.getFetcherClassName(tag), queue, proc, tag);
		
		logger.info("init file queue...");
		queue.initQueue(fetcher);
		/*获取器的启动必须放在队列初始化之后，因为它需要获取队列尾部的文件*/
		logger.info("start file fetcher...");
		fetcher.start();
		
		logger.info("new logFileHandler...");
		LogFileHandler fileHandler = new LogFileHandler(queue,proc,tag);
		
		logger.info("init log sending...");
		IMsgHandler msgHandler = FactoryService.getMsgHandler(config.getMessageHandlerClassName(tag), tag, context);
		
		logger.info("add into real time monitor...");
		monitor.addMonitorData(new RealTimeMonitorData(tag, queue));
		
		logger.info("read log from file and sending...");
		
		
		try{
			/*发送消息*/
			if(config.MSG_TYPE_STRING.equals(config.getMessageType(tag))){
				this.sendStringMessage(msgHandler, fileHandler);
			}else if(config.MSG_TYPE_BYTES.endsWith(config.getMessageType(tag))){
				this.sendBytesMessage(msgHandler, fileHandler);
			}else{
				logger.warn("unknow message type:"+config.getMessageType(tag));
			}
			
			
		}catch (Exception e) {
			logger.error("global exception, tag="+tag,e);
		}
		
		
		
	}
	
	/**
	 * 对于不带有中文字符的可以使用String类型，中文字符会有乱码
	 * */
	private void sendStringMessage(IMsgHandler msgHandler, IFileHandler fileHandler){
		String line = fileHandler.readLine();
		boolean flag = false;
		/*计算出现超时时，发送的日志的数量*/
		int count = 0;
		while(true){
//			logger.info(tag+":"+line);
			long startTime = System.currentTimeMillis();
			
			//block util msg can be sent
			flag = msgHandler.sendMsg(line);
			
			long endTime_2 = System.currentTimeMillis();
			
			//block util new line can be read
			line = fileHandler.readLine();			
			long endTime = System.currentTimeMillis();
			
			count++;
			/*数据成功发送,超时，则打印日志*/
			if(endTime-startTime>config.getLogTimeout()){
				if(flag){
					logger.info(new StringBuffer(tag).
							append(":read new line and send successfully, spend ").
							append(endTime-endTime_2).
							append("ms, send spend ").
							append(endTime_2-startTime).append("ms total count:").
							append(count).
							toString());
					count = 0;
				}
			}
			
		}
		
	}
	/**
	 * 字节类型是通用的
	 * */
	private void sendBytesMessage(IMsgHandler msgHandler, IFileHandler fileHandler){
		byte[] bytes = fileHandler.readBytes();
		boolean flag = false;
		/*计算出现超时时，发送的日志的数量*/
		int count = 0;
		while(true){
//			logger.info(tag+":"+line);
			long startTime = System.currentTimeMillis();
			
			//block util msg can be sent
			flag = msgHandler.sendMsg(bytes);
//			logger.warn("client:"+new String(bytes));
			
			long endTime_2 = System.currentTimeMillis();
			
			//block util new line can be read
			bytes = fileHandler.readBytes();			
			long endTime = System.currentTimeMillis();
			
			count++;
			/*数据成功发送,超时，则打印日志*/
			if(endTime-startTime>config.getLogTimeout()){
				if(flag){
					logger.info(new StringBuffer(tag).
							append(":read new bytes and send successfully, spend ").
							append(endTime-startTime).
							append("ms, soketSend spend ").
							append(endTime_2-startTime).append("ms total count:").
							append(count).
							toString());
					count = 0;
				}
			}
			
		}
	}
}
